/*
 * OPIAM Suite
 *
 * Distributable under LGPL license.
 * See terms of license at gnu.org.
 */

package opiam.admin.faare.admin;

import opiam.admin.faare.config.javabeans.JBProfiles;

import org.apache.commons.digester.Digester;

import org.apache.log4j.Logger;

import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

import java.io.IOException;
import java.io.InputStream;


/**
 * Resources and profiles configuration loading from the XML file.
 *
 * The XML file must contain the following lines :
 * <!DOCTYPE mapping PUBLIC
 *         "-//OPIAM ADMIN//DTD Profiles Service Configuration 1.0//EN"
 *         "http://www.opiam.org/admin/dtd/profiles_conf.dtd">
 *
 * The second line is registered to the digester (it does not need to be an actual URL).
 *
 * Classe identique a celle du package opiam.admin.faare.config
 * mais qui evite de charger tout le FAARE (classe
 * opiam.admin.faare.admin.JBRessource au lieu de
 * opiam.admin.faare.config.javabeans.JBRessource
 */
public final class ProfilesConfig implements ErrorHandler
{
    /** DOCTYPE key. */
    public static final String PROFILES_CONFIG_DTD_KEY = "-//OPIAM ADMIN//DTD Profiles Service Configuration 1.0//EN";

    /** DOCTYPE URL. */
    public static final String PROFILES_CONFIG_DTD_URL = "/config/core/profiles_config.dtd";

    /** Log4J. */
    private static Logger _logger = Logger.getLogger(ProfilesConfig.class.getName());

    /** XML Parser. */
    private static Digester _profileDigester = null;

    /** Current instance. */
    private static ProfilesConfig _instance = null;

    /** Parser exception. */
    private static SAXParseException _saxParseException = null;

    /**
     * Constructor for ProfilesDigester.
     */
    private ProfilesConfig()
    {
        super();
    }

    /**
     * Digester initialization with DTD fields.
     */
    private static void initProfileDigester()
    {
        _saxParseException = null;

        _profileDigester = new Digester();

        _profileDigester.setErrorHandler(_instance);
        _profileDigester.setValidating(true);

        _profileDigester.register(PROFILES_CONFIG_DTD_KEY,
            ProfilesConfig.class.getResource(PROFILES_CONFIG_DTD_URL).toString());

        _profileDigester.addObjectCreate("profiles",
            "opiam.admin.faare.config.javabeans.JBProfiles");

        _profileDigester.addObjectCreate("profiles/ressource",
            "opiam.admin.faare.admin.JBRessource");
        _profileDigester.addSetNext("profiles/ressource", "addRessource",
            "opiam.admin.faare.admin.JBRessource");
        _profileDigester.addSetProperties("profiles/ressource");

        _profileDigester.addCallMethod("profiles/ressource/param", "addParam", 2);
        _profileDigester.addCallParam("profiles/ressource/param/param-name", 0);
        _profileDigester.addCallParam("profiles/ressource/param/param-value", 1);

        _profileDigester.addObjectCreate("profiles/profile_user",
            "opiam.admin.faare.config.javabeans.JBProfile");
        _profileDigester.addSetNext("profiles/profile_user", "addProfileUser",
            "opiam.admin.faare.config.javabeans.JBProfile");
        _profileDigester.addSetProperties("profiles/profile_user");

        _profileDigester.addObjectCreate("profiles/profile_user/ressources",
            "opiam.admin.faare.config.javabeans.JBRessources");
        _profileDigester.addSetNext("profiles/profile_user/ressources",
            "setJbRessources",
            "opiam.admin.faare.config.javabeans.JBRessources");

        _profileDigester.addObjectCreate("profiles/profile_user/ressources/ressource",
            "opiam.admin.faare.admin.JBRessource");
        _profileDigester.addSetNext("profiles/profile_user/ressources/ressource",
            "addRessource", "opiam.admin.faare.admin.JBRessource");
        _profileDigester.addSetProperties(
            "profiles/profile_user/ressources/ressource");

        _profileDigester.addCallMethod("profiles/profile_user/ressources/ressource/param",
            "addParam", 2);
        _profileDigester.addCallParam("profiles/profile_user/ressources/ressource/param/param-name",
            0);
        _profileDigester.addCallParam("profiles/profile_user/ressources/ressource/param/param-value",
            1);

        _profileDigester.addObjectCreate("profiles/profile_staticgroup",
            "opiam.admin.faare.config.javabeans.JBProfile");
        _profileDigester.addSetNext("profiles/profile_staticgroup",
            "addProfileStaticGroup",
            "opiam.admin.faare.config.javabeans.JBProfile");
        _profileDigester.addSetProperties("profiles/profile_staticgroup");

        _profileDigester.addObjectCreate("profiles/profile_staticgroup/ressources",
            "opiam.admin.faare.config.javabeans.JBRessources");
        _profileDigester.addSetNext("profiles/profile_staticgroup/ressources",
            "setJbRessources",
            "opiam.admin.faare.config.javabeans.JBRessources");

        _profileDigester.addObjectCreate("profiles/profile_staticgroup/ressources/ressource",
            "opiam.admin.faare.admin.JBRessource");
        _profileDigester.addSetNext("profiles/profile_staticgroup/ressources/ressource",
            "addRessource", "opiam.admin.faare.admin.JBRessource");
        _profileDigester.addSetProperties(
            "profiles/profile_staticgroup/ressources/ressource");

        _profileDigester.addCallMethod("profiles/profile_staticgroup/ressources/ressource/param",
            "addParam", 2);
        _profileDigester.addCallParam("profiles/profile_staticgroup/ressources/ressource/param/param-name",
            0);
        _profileDigester.addCallParam("profiles/profile_staticgroup/ressources/ressource/param/param-value",
            1);

        _profileDigester.addObjectCreate("profiles/profile_dynamicgroup",
            "opiam.admin.faare.config.javabeans.JBProfile");
        _profileDigester.addSetNext("profiles/profile_dynamicgroup",
            "addProfileDynamicGroup",
            "opiam.admin.faare.config.javabeans.JBProfile");
        _profileDigester.addSetProperties("profiles/profile_dynamicgroup");

        _profileDigester.addObjectCreate("profiles/profile_dynamicgroup/ressources",
            "opiam.admin.faare.config.javabeans.JBRessources");
        _profileDigester.addSetNext("profiles/profile_dynamicgroup/ressources",
            "setJbRessources",
            "opiam.admin.faare.config.javabeans.JBRessources");

        _profileDigester.addObjectCreate("profiles/profile_dynamicgroup/ressources/ressource",
            "opiam.admin.faare.admin.JBRessource");
        _profileDigester.addSetNext("profiles/profile_dynamicgroup/ressources/ressource",
            "addRessource", "opiam.admin.faare.admin.JBRessource");
        _profileDigester.addSetProperties(
            "profiles/profile_dynamicgroup/ressources/ressource");

        _profileDigester.addCallMethod("profiles/profile_dynamicgroup/ressources/ressource/param",
            "addParam", 2);
        _profileDigester.addCallParam("profiles/profile_dynamicgroup/ressources/ressource/param/param-name",
            0);
        _profileDigester.addCallParam("profiles/profile_dynamicgroup/ressources/ressource/param/param-value",
            1);

        _profileDigester.addObjectCreate("profiles/profile_filter",
            "opiam.admin.faare.config.javabeans.JBProfile");
        _profileDigester.addSetNext("profiles/profile_filter",
            "addProfileFilter",
            "opiam.admin.faare.config.javabeans.JBProfile");
        _profileDigester.addSetProperties("profiles/profile_filter");

        _profileDigester.addObjectCreate("profiles/profile_filter/ressources",
            "opiam.admin.faare.config.javabeans.JBRessources");
        _profileDigester.addSetNext("profiles/profile_filter/ressources",
            "setJbRessources",
            "opiam.admin.faare.config.javabeans.JBRessources");

        _profileDigester.addObjectCreate("profiles/profile_filter/ressources/ressource",
            "opiam.admin.faare.admin.JBRessource");
        _profileDigester.addSetNext("profiles/profile_filter/ressources/ressource",
            "addRessource", "opiam.admin.faare.admin.JBRessource");
        _profileDigester.addSetProperties(
            "profiles/profile_filter/ressources/ressource");

        _profileDigester.addCallMethod("profiles/profile_filter/ressources/ressource/param",
            "addParam", 2);
        _profileDigester.addCallParam("profiles/profile_filter/ressources/ressource/param/param-name",
            0);
        _profileDigester.addCallParam("profiles/profile_filter/ressources/ressource/param/param-value",
            1);

        _profileDigester.addObjectCreate("profiles/profile_default",
            "opiam.admin.faare.config.javabeans.JBProfile");
        _profileDigester.addSetNext("profiles/profile_default",
            "addProfileDefault",
            "opiam.admin.faare.config.javabeans.JBProfile");
        _profileDigester.addSetProperties("profiles/profile_default");

        _profileDigester.addObjectCreate("profiles/profile_default/ressources",
            "opiam.admin.faare.config.javabeans.JBRessources");
        _profileDigester.addSetNext("profiles/profile_default/ressources",
            "setJbRessources",
            "opiam.admin.faare.config.javabeans.JBRessources");

        _profileDigester.addObjectCreate("profiles/profile_default/ressources/ressource",
            "opiam.admin.faare.admin.JBRessource");
        _profileDigester.addSetNext("profiles/profile_default/ressources/ressource",
            "addRessource", "opiam.admin.faare.admin.JBRessource");
        _profileDigester.addSetProperties(
            "profiles/profile_default/ressources/ressource");

        _profileDigester.addCallMethod("profiles/profile_default/ressources/ressource/param",
            "addParam", 2);
        _profileDigester.addCallParam("profiles/profile_default/ressources/ressource/param/param-name",
            0);
        _profileDigester.addCallParam("profiles/profile_default/ressources/ressource/param/param-value",
            1);

        //DW/2618/BeginPatch
        _profileDigester.addObjectCreate("profiles/staticgroup",
            "opiam.admin.faare.config.javabeans.JBGroupDef");
        _profileDigester.addSetNext("profiles/staticgroup", "setStaticGroup",
            "opiam.admin.faare.config.javabeans.JBGroupDef");
        _profileDigester.addSetProperties("profiles/staticgroup");

        _profileDigester.addObjectCreate("profiles/dynamicgroup",
            "opiam.admin.faare.config.javabeans.JBGroupDef");
        _profileDigester.addSetNext("profiles/dynamicgroup", "setDynamicGroup",
            "opiam.admin.faare.config.javabeans.JBGroupDef");
        _profileDigester.addSetProperties("profiles/dynamicgroup");

        //DW/2618/EndPatch
        //DW/2630/BeginPatch
        _profileDigester.addObjectCreate("profiles/resource",
            "opiam.admin.faare.admin.JBRessource");
        _profileDigester.addSetNext("profiles/resource", "addRessource",
            "opiam.admin.faare.admin.JBRessource");
        _profileDigester.addSetProperties("profiles/resource");

        _profileDigester.addCallMethod("profiles/resource/param", "addParam", 2);
        _profileDigester.addCallParam("profiles/resource/param/param-name", 0);
        _profileDigester.addCallParam("profiles/resource/param/param-value", 1);

        _profileDigester.addObjectCreate("profiles/profile_user/resources",
            "opiam.admin.faare.config.javabeans.JBRessources");
        _profileDigester.addSetNext("profiles/profile_user/resources",
            "setJbRessources",
            "opiam.admin.faare.config.javabeans.JBRessources");

        _profileDigester.addObjectCreate("profiles/profile_user/resources/resource",
            "opiam.admin.faare.admin.JBRessource");
        _profileDigester.addSetNext("profiles/profile_user/resources/resource",
            "addRessource", "opiam.admin.faare.admin.JBRessource");
        _profileDigester.addSetProperties(
            "profiles/profile_user/resources/resource");

        _profileDigester.addCallMethod("profiles/profile_user/resources/resource/param",
            "addParam", 2);
        _profileDigester.addCallParam("profiles/profile_user/resources/resource/param/param-name",
            0);
        _profileDigester.addCallParam("profiles/profile_user/resources/resource/param/param-value",
            1);

        _profileDigester.addObjectCreate("profiles/profile_staticgroup/resources",
            "opiam.admin.faare.config.javabeans.JBRessources");
        _profileDigester.addSetNext("profiles/profile_staticgroup/resources",
            "setJbRessources",
            "opiam.admin.faare.config.javabeans.JBRessources");

        _profileDigester.addObjectCreate("profiles/profile_staticgroup/resources/resource",
            "opiam.admin.faare.admin.JBRessource");
        _profileDigester.addSetNext("profiles/profile_staticgroup/resources/resource",
            "addRessource", "opiam.admin.faare.admin.JBRessource");
        _profileDigester.addSetProperties(
            "profiles/profile_staticgroup/resources/resource");

        _profileDigester.addCallMethod("profiles/profile_staticgroup/resources/resource/param",
            "addParam", 2);
        _profileDigester.addCallParam("profiles/profile_staticgroup/resources/resource/param/param-name",
            0);
        _profileDigester.addCallParam("profiles/profile_staticgroup/resources/resource/param/param-value",
            1);

        _profileDigester.addObjectCreate("profiles/profile_dynamicgroup/resources",
            "opiam.admin.faare.config.javabeans.JBRessources");
        _profileDigester.addSetNext("profiles/profile_dynamicgroup/resources",
            "setJbRessources",
            "opiam.admin.faare.config.javabeans.JBRessources");

        _profileDigester.addObjectCreate("profiles/profile_dynamicgroup/resources/resource",
            "opiam.admin.faare.admin.JBRessource");
        _profileDigester.addSetNext("profiles/profile_dynamicgroup/resources/resource",
            "addRessource", "opiam.admin.faare.admin.JBRessource");
        _profileDigester.addSetProperties(
            "profiles/profile_dynamicgroup/resources/resource");

        _profileDigester.addCallMethod("profiles/profile_dynamicgroup/resources/resource/param",
            "addParam", 2);
        _profileDigester.addCallParam("profiles/profile_dynamicgroup/resources/resource/param/param-name",
            0);
        _profileDigester.addCallParam("profiles/profile_dynamicgroup/resources/resource/param/param-value",
            1);

        _profileDigester.addObjectCreate("profiles/profile_filter/resources",
            "opiam.admin.faare.config.javabeans.JBRessources");
        _profileDigester.addSetNext("profiles/profile_filter/resources",
            "setJbRessources",
            "opiam.admin.faare.config.javabeans.JBRessources");

        _profileDigester.addObjectCreate("profiles/profile_filter/resources/resource",
            "opiam.admin.faare.admin.JBRessource");
        _profileDigester.addSetNext("profiles/profile_filter/resources/resource",
            "addRessource", "opiam.admin.faare.admin.JBRessource");
        _profileDigester.addSetProperties(
            "profiles/profile_filter/resources/resource");

        _profileDigester.addCallMethod("profiles/profile_filter/resources/resource/param",
            "addParam", 2);
        _profileDigester.addCallParam("profiles/profile_filter/resources/resource/param/param-name",
            0);
        _profileDigester.addCallParam("profiles/profile_filter/resources/resource/param/param-value",
            1);

        _profileDigester.addObjectCreate("profiles/profile_default/resources",
            "opiam.admin.faare.config.javabeans.JBRessources");
        _profileDigester.addSetNext("profiles/profile_default/resources",
            "setJbRessources",
            "opiam.admin.faare.config.javabeans.JBRessources");

        _profileDigester.addObjectCreate("profiles/profile_default/resources/resource",
            "opiam.admin.faare.admin.JBRessource");
        _profileDigester.addSetNext("profiles/profile_default/resources/resource",
            "addRessource", "opiam.admin.faare.admin.JBRessource");
        _profileDigester.addSetProperties(
            "profiles/profile_default/resources/resource");

        _profileDigester.addCallMethod("profiles/profile_default/resources/resource/param",
            "addParam", 2);
        _profileDigester.addCallParam("profiles/profile_default/resources/resource/param/param-name",
            0);
        _profileDigester.addCallParam("profiles/profile_default/resources/resource/param/param-value",
            1);

        //DW/2630/EndPatch
    }

    /**
     * Gets ProfilesConfig instance.
     *
     * @return ProfilesConfig instance
     */
    public static ProfilesConfig getInstance()
    {
        if (_instance == null)
        {
            _instance = new ProfilesConfig();
            initProfileDigester();
        }

        return _instance;
    }

    /**
     * Gets Resources and Profiles config.
     *
     * @param in configuration stream
     *
     * @return Resources and Profiles config
     *
     * @throws IOException exception while reading stream.
     * @throws SAXException exception while parsing data.
     */
    public JBProfiles readConfig(InputStream in)
        throws IOException, SAXException
    {
        _logger.debug("readConfig1 ");

        JBProfiles result = null;
        result = (JBProfiles) _profileDigester.parse(in);

        if (_saxParseException != null)
        {
            _logger.debug("Exception : " + _saxParseException.getMessage());
            throw new SAXException(_saxParseException.getMessage());
        }

        return result;
    }

    /**
     * Parsing error callback.
     *
     * @param saxParseException parsing exception
     */
    public void error(SAXParseException saxParseException)
    {
        _logger.debug(" error exception!!!!!!!!!!!!!!!");
        _saxParseException = saxParseException;
    }

    /**
     * Parsing fatal error callback.
     *
     * @param saxParseException parsing exception
     */
    public void fatalError(SAXParseException saxParseException)
    {
        _logger.debug("fatalError exception!!!!!!!!!!!!!!!");
        _saxParseException = saxParseException;
    }

    /**
     * Parsing warning callback.
     *
     * @param saxParseException parsing exception
     */
    public void warning(SAXParseException saxParseException)
    {
        _logger.debug("warning : " + saxParseException.getMessage());
    }
}
